Queue Implementation: The Circular Buffer

PolyU DSAI2201 Lecture 13 2025-11-25

Efficient Queue Implementation: The Circular Buffer

A standard array-based queue requires $O(N)$ time complexity for the dequeue operation because all subsequent elements must be shifted forward. To achieve efficient $O(1)$ operation time, we use a Circular Buffer (or Ring Queue).

The Circular Buffer uses a fixed-size array (Capacity) and two pointers: front (for dequeue) and rear (for enqueue). The array acts as a continuous loop using the modulo operator (%) to handle index wrapping.

OperationPointer LogicEffect
Enqueue (Add)rear = (rear + 1) % CapacityInserts at the next available spot.
Dequeue (Remove)front = (front + 1) % CapacityMoves the starting point forward.
Benefit: This structure ensures both insertion and removal take constant time, regardless of the queue size.

Performance Analysis (Circular Buffer)

The primary advantage of the Circular Buffer is achieving $O(1)$ time complexity for all core operations, making it highly suitable for real-time systems and fixed-memory constraints.

OperationTime ComplexitySpace ComplexityDetails
Enqueue$O(1)$$O(N)$ FixedConstant time addition.
Dequeue$O(1)$$O(N)$ FixedConstant time removal (no shifting).
Peek (Front)$O(1)$$O(1)$Directly accesses front index.

Implementation Caveats: Full vs. Empty

A major challenge in circular buffer implementation is that both an empty queue and a full queue can result in front == rear.

Two Common Solutions:

  1. The Sentinel Approach: Always leave one slot empty. The queue is full when (rear + 1) % Capacity == front.
  2. The Counter Approach: Maintain an explicit integer count variable. If count == 0, it is empty; if count == Capacity, it is full. This removes the need to waste a slot.
📝 Interactive Quiz

1. In a circular buffer with Capacity = 10, the current rear pointer is at index 9. Which index will the next element be inserted into after the next enqueue operation?

  • A) Index 10 (Out of Bounds Error)
  • B) Index 9 (Overwrite)
  • C) Index 0
  • D) Index 1

2. What is the primary performance advantage of using a circular buffer for a queue compared to a standard array implementation?

  • A) It uses less memory overall.
  • B) dequeue is $O(1)$ because it avoids shifting elements.
  • C) It can grow dynamically without limit.
  • D) enqueue operations are faster.

3. A circular buffer faces an ambiguity where front == rear can mean the buffer is either full or empty. Which is a common solution to this problem?

  • A) Doubling the array size when this happens.
  • B) Using a linked list instead of an array.
  • C) Maintaining a separate count variable for the number of elements.
  • D) Resetting both pointers to -1.